﻿using System;
using System.Collections.Generic;
using System.Linq;
using DataModel.Models;

namespace DataModel.Managers
{
    public class GroupManager
    {
        readonly UniversityPortalEntities _entityModel;

        public GroupManager()
        {
            _entityModel = new UniversityPortalEntities();
        }

        public void CreateGroup(long number, Guid specialityID, DateTime entranceDate, int amountYears)
        {
            try
            {
                Speciality speciality = _entityModel.Specialities.First(specialityItem => specialityItem.ID == specialityID);
                string specialityName = speciality.fullName;
                Department department = _entityModel.Departments.First(departmentItem => departmentItem.ID == speciality.depatmentID);
                string departmentName = department.fullName;
                if (_entityModel.Groups.Any(groupItem => (groupItem.number == number) && (groupItem.specialityID == speciality.ID)))
                {
                    throw new Exception(
                        string.Format("Group {0} in speciality \"{1}\" in departament \"{2}\" already exists",
                                      number, specialityName, departmentName));
                }

                var group = new Group();
                group.ID = Guid.NewGuid();
                group.number = number;
                group.specialityID = specialityID;
                group.entranceDate = entranceDate;
                group.amountYears = amountYears;

                _entityModel.AddToGroups(group);
                _entityModel.SaveChanges();
            }
            catch (Exception)
            {

                throw new Exception("Additing group error.");
            }
        }

        public void CreateGroup(long number, string specialityShortName, DateTime entranceDate, int amountYears)
        {
            CreateGroup(number, (new SpecialityManager()).GetSpecialityGuid(specialityShortName), entranceDate, amountYears);
        }

        public Guid GetGroupGuid(long number)
        {
            return _entityModel.Groups.First(gr => gr.number == number).ID;
        }

        public GroupModel GetGroupModel(Group group)
        {
            var groupModel = new GroupModel(group);
            return groupModel;
        }

        /// <summary>
        /// Returns GroupModel by group number
        /// </summary>
        /// <param name="groupNumber">group number</param>
        /// <returns>group model</returns>
        public GroupModel GetGroupByNumber(long groupNumber)
        {
            var group = _entityModel.Groups.FirstOrDefault(groupItem => groupItem.number == groupNumber);
            return (group != null) ? GetGroupModel(group) : null;
        }

        public GroupModel GetGroupByNumber(Guid groupID)
        {
            var group = _entityModel.Groups.FirstOrDefault(groupItem => groupItem.ID == groupID);
            return (group != null) ? GetGroupModel(group) : null;
        }

        public IEnumerable<GroupModel> GetAllGroups()
        {
            var list = new List<GroupModel>();
            foreach (var group in _entityModel.Groups)
            {
                list.Add(new GroupModel(group));
            }
            return list.OrderBy(g => g.Number).AsEnumerable();
        }

        public List<SubjectModel> GetAllGroupSubjects(Int64 groupNumber, int semester = 0)
        {
            List<SubjectModel> subjectModels = null;
            Group currentGroup = _entityModel.Groups.FirstOrDefault(g => g.number == groupNumber);
            if (currentGroup != null)
            {
                semester = (semester <= 0) ? currentGroup.GetCurrentSemester() : semester;

                var subjects =
                    (from s in currentGroup.Lessons where s.semester == semester select s.Subject).Distinct(
                        new SubjectComparer());

                subjectModels = subjects.Select(sub => new SubjectModel
                                                           {
                                                               Desription = sub.desription,
                                                               FullName = sub.fullName,
                                                               ShortName = sub.shortName,
                                                               SubjectID = sub.ID
                                                           }).ToList();
            }
            return subjectModels;
        }

        public List<StudentModel> GetAllStudentsByGroup(Guid id)
        {
            List<StudentModel> studentModels = null;
            Group group = _entityModel.Groups.FirstOrDefault(groupItem => groupItem.ID == id);

            if (group != null)
            {
                studentModels = group.Students.Select(student => new StudentModel(student)).ToList();
            }
            return studentModels;
        }

        public IEnumerable<GroupModel> GetGroupsInSpeciality(Guid specialityID)
        {
            var specialityManager = new SpecialityManager();
            return specialityManager.GetSpeciality(specialityID).Groups.AsEnumerable();
        }

        public long GetGroupNumber(Guid groupId)
        {
            long groupNumber = -1;
            Group group = _entityModel.Groups.FirstOrDefault(item => item.ID == groupId);
            if (group != null)
            {
                groupNumber = group.number;
            }
            return groupNumber;
        }
    }
}
